<!-- htmlhint doctype-first:false, tag-pair:false -->
<!-- Advanced Metrics Dashboard -->
<script>
// Metrics Dashboard Controller Factory
window.createMetricsController = function() {
  return {
    timeRange: 24,
    interval: 60,
    limit: 10,
    charts: {},
    loading: false,
    error: null,
    async init() {
      await this.loadAllMetrics();
      this.startAutoRefresh();
    },
    async loadAllMetrics() {
      this.loading = true;
      this.error = null;
      try {
        await Promise.all([
          this.loadPercentiles(),
          this.loadTimeSeries(),
          this.loadTopSlow(),
          this.loadTopVolume(),
          this.loadTopErrors(),
          this.loadHeatmap(),
        ]);
      } catch (e) {
        console.error('Failed to load metrics:', e);
        this.error = e.message;
      } finally {
        this.loading = false;
      }
    },
    async loadPercentiles() {
      const response = await fetch(
        `{{ root_path }}/admin/observability/metrics/percentiles?hours=${this.timeRange}&interval_minutes=${this.interval}`
      );
      if (!response.ok) throw new Error('Failed to load percentiles');
      const data = await response.json();
      this.renderPercentileChart(data);
    },
    async loadTimeSeries() {
      const response = await fetch(
        `{{ root_path }}/admin/observability/metrics/timeseries?hours=${this.timeRange}&interval_minutes=${this.interval}`
      );
      if (!response.ok) throw new Error('Failed to load time series');
      const data = await response.json();
      this.renderTimeSeriesChart(data);
    },
    async loadTopSlow() {
      const response = await fetch(
        `{{ root_path }}/admin/observability/metrics/top-slow?hours=${this.timeRange}&limit=${this.limit}`
      );
      if (!response.ok) throw new Error('Failed to load top slow endpoints');
      const data = await response.json();
      this.renderTopSlowTable(data);
    },
    async loadTopVolume() {
      const response = await fetch(
        `{{ root_path }}/admin/observability/metrics/top-volume?hours=${this.timeRange}&limit=${this.limit}`
      );
      if (!response.ok) throw new Error('Failed to load top volume endpoints');
      const data = await response.json();
      this.renderTopVolumeTable(data);
    },
    async loadTopErrors() {
      const response = await fetch(
        `{{ root_path }}/admin/observability/metrics/top-errors?hours=${this.timeRange}&limit=${this.limit}`
      );
      if (!response.ok) throw new Error('Failed to load top error endpoints');
      const data = await response.json();
      this.renderTopErrorsTable(data);
    },
    async loadHeatmap() {
      const response = await fetch(
        `{{ root_path }}/admin/observability/metrics/heatmap?hours=${this.timeRange}&time_buckets=24&latency_buckets=20`
      );
      if (!response.ok) throw new Error('Failed to load heatmap');
      const data = await response.json();
      this.renderHeatmap(data);
    },
    renderPercentileChart(data) {
      const ctx = document.getElementById('percentileChart');
      if (!ctx) return;

      if (this.charts.percentile) {
        this.charts.percentile.destroy();
      }

      this.charts.percentile = new Chart(ctx, {
        type: 'line',
        data: {
          labels: data.timestamps.map((t) => new Date(t).toLocaleTimeString()),
          datasets: [
            {
              label: 'p50 (median)',
              data: data.p50,
              borderColor: '#10b981',
              backgroundColor: 'rgba(16, 185, 129, 0.1)',
              fill: true,
            },
            {
              label: 'p90',
              data: data.p90,
              borderColor: '#3b82f6',
              backgroundColor: 'rgba(59, 130, 246, 0.1)',
              fill: true,
            },
            {
              label: 'p95',
              data: data.p95,
              borderColor: '#f59e0b',
              backgroundColor: 'rgba(245, 158, 11, 0.1)',
              fill: true,
            },
            {
              label: 'p99',
              data: data.p99,
              borderColor: '#ef4444',
              backgroundColor: 'rgba(239, 68, 68, 0.1)',
              fill: true,
            },
          ],
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          interaction: {
            mode: 'index',
            intersect: false,
          },
          plugins: {
            title: {
              display: true,
              text: 'Latency Percentiles Over Time',
            },
            legend: {
              position: 'bottom',
            },
            tooltip: {
              callbacks: {
                label: function (context) {
                  return context.dataset.label + ': ' + context.parsed.y.toFixed(2) + ' ms';
                },
              },
            },
          },
          scales: {
            y: {
              beginAtZero: true,
              title: {
                display: true,
                text: 'Latency (ms)',
              },
            },
          },
        },
      });
    },
    renderTimeSeriesChart(data) {
      const ctx = document.getElementById('timeSeriesChart');
      if (!ctx) return;

      if (this.charts.timeSeries) {
        this.charts.timeSeries.destroy();
      }

      this.charts.timeSeries = new Chart(ctx, {
        type: 'line',
        data: {
          labels: data.timestamps.map((t) => new Date(t).toLocaleTimeString()),
          datasets: [
            {
              label: 'Total Requests',
              data: data.request_count,
              borderColor: '#3b82f6',
              backgroundColor: 'rgba(59, 130, 246, 0.1)',
              yAxisID: 'y',
              fill: true,
            },
            {
              label: 'Error Rate (%)',
              data: data.error_rate,
              borderColor: '#ef4444',
              backgroundColor: 'rgba(239, 68, 68, 0.1)',
              yAxisID: 'y1',
              fill: true,
            },
          ],
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          interaction: {
            mode: 'index',
            intersect: false,
          },
          plugins: {
            title: {
              display: true,
              text: 'Request Rate & Error Rate',
            },
            legend: {
              position: 'bottom',
            },
          },
          scales: {
            y: {
              type: 'linear',
              display: true,
              position: 'left',
              title: {
                display: true,
                text: 'Requests',
              },
            },
            y1: {
              type: 'linear',
              display: true,
              position: 'right',
              title: {
                display: true,
                text: 'Error Rate (%)',
              },
              grid: {
                drawOnChartArea: false,
              },
            },
          },
        },
      });
    },
    renderTopSlowTable(data) {
      const tbody = document.querySelector('#topSlowTable tbody');
      if (!tbody) return;

      tbody.innerHTML = data.endpoints
        .map(
          (ep, idx) => `
            <tr>
              <td class="px-4 py-2 text-sm text-gray-700">${idx + 1}</td>
              <td class="px-4 py-2 text-sm font-mono text-gray-900">${ep.endpoint}</td>
              <td class="px-4 py-2 text-sm text-gray-600">${ep.count}</td>
              <td class="px-4 py-2 text-sm text-orange-600 font-medium">${ep.avg_duration_ms} ms</td>
              <td class="px-4 py-2 text-sm text-red-600">${ep.max_duration_ms} ms</td>
            </tr>
          `
        )
        .join('');
    },
    renderTopVolumeTable(data) {
      const tbody = document.querySelector('#topVolumeTable tbody');
      if (!tbody) return;

      tbody.innerHTML = data.endpoints
        .map(
          (ep, idx) => `
            <tr>
              <td class="px-4 py-2 text-sm text-gray-700">${idx + 1}</td>
              <td class="px-4 py-2 text-sm font-mono text-gray-900">${ep.endpoint}</td>
              <td class="px-4 py-2 text-sm font-medium text-blue-600">${ep.count}</td>
              <td class="px-4 py-2 text-sm text-gray-600">${ep.avg_duration_ms} ms</td>
            </tr>
          `
        )
        .join('');
    },
    renderTopErrorsTable(data) {
      const tbody = document.querySelector('#topErrorsTable tbody');
      if (!tbody) return;

      tbody.innerHTML = data.endpoints
        .map(
          (ep, idx) => `
            <tr>
              <td class="px-4 py-2 text-sm text-gray-700">${idx + 1}</td>
              <td class="px-4 py-2 text-sm font-mono text-gray-900">${ep.endpoint}</td>
              <td class="px-4 py-2 text-sm text-gray-600">${ep.total_count}</td>
              <td class="px-4 py-2 text-sm text-red-600 font-medium">${ep.error_count}</td>
              <td class="px-4 py-2 text-sm text-red-700 font-bold">${ep.error_rate}%</td>
            </tr>
          `
        )
        .join('');
    },
    renderHeatmap(data) {
      const ctx = document.getElementById('heatmapChart');
      if (!ctx) return;

      if (this.charts.heatmap) {
        this.charts.heatmap.destroy();
      }

      // Flatten the 2D heatmap data for Chart.js matrix
      const heatmapData = [];
      for (let y = 0; y < data.data.length; y++) {
        for (let x = 0; x < data.data[y].length; x++) {
          heatmapData.push({
            x: x,
            y: y,
            v: data.data[y][x],
          });
        }
      }

      this.charts.heatmap = new Chart(ctx, {
        type: 'scatter',
        data: {
          datasets: [
            {
              label: 'Request Count',
              data: heatmapData,
              backgroundColor: function (context) {
                const value = context.raw.v;
                const maxValue = Math.max(...heatmapData.map((d) => d.v));
                const alpha = value / maxValue;
                return `rgba(239, 68, 68, ${alpha})`;
              },
              pointRadius: 10,
              pointHoverRadius: 12,
            },
          ],
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          plugins: {
            title: {
              display: true,
              text: 'Latency Distribution Heatmap',
            },
            legend: {
              display: false,
            },
            tooltip: {
              callbacks: {
                title: function (context) {
                  const timeLabel = data.time_labels[context[0].raw.x];
                  const latencyLabel = data.latency_labels[context[0].raw.y];
                  return `${timeLabel} - ${latencyLabel}`;
                },
                label: function (context) {
                  return `Requests: ${context.raw.v}`;
                },
              },
            },
          },
          scales: {
            x: {
              type: 'linear',
              position: 'bottom',
              ticks: {
                stepSize: 1,
                callback: function (value) {
                  return data.time_labels[value] || '';
                },
              },
              title: {
                display: true,
                text: 'Time',
              },
            },
            y: {
              type: 'linear',
              ticks: {
                stepSize: 1,
                callback: function (value) {
                  return data.latency_labels[value] || '';
                },
              },
              title: {
                display: true,
                text: 'Latency',
              },
            },
          },
        },
      });
    },
    startAutoRefresh() {
      // Refresh every 60 seconds
      setInterval(() => this.loadAllMetrics(), 60000);
    },
    async applyFilters() {
      await this.loadAllMetrics();
    }
  };
};
</script>

<div class="metrics-dashboard" x-data="createMetricsController()" x-init="init()">
  <!-- Controls -->
  <div class="mb-6 p-4 bg-white dark:bg-gray-800 rounded-lg shadow">
    <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
          >Time Range</label
        >
        <select
          x-model="timeRange"
          @change="applyFilters()"
          class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
        >
          <option value="1">Last Hour</option>
          <option value="6">Last 6 Hours</option>
          <option value="24" selected>Last 24 Hours</option>
          <option value="72">Last 3 Days</option>
          <option value="168">Last 7 Days</option>
        </select>
      </div>

      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
          >Interval</label
        >
        <select
          x-model="interval"
          @change="applyFilters()"
          class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
        >
          <option value="5">5 Minutes</option>
          <option value="15">15 Minutes</option>
          <option value="60" selected>1 Hour</option>
          <option value="360">6 Hours</option>
          <option value="1440">1 Day</option>
        </select>
      </div>

      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
          >Top N Limit</label
        >
        <select
          x-model="limit"
          @change="applyFilters()"
          class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
        >
          <option value="5">Top 5</option>
          <option value="10" selected>Top 10</option>
          <option value="20">Top 20</option>
          <option value="50">Top 50</option>
        </select>
      </div>

      <div class="flex items-end">
        <button
          @click="applyFilters()"
          :disabled="loading"
          class="w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
        >
          <span x-show="!loading">Refresh</span>
          <span x-show="loading">Loading...</span>
        </button>
      </div>
    </div>

    <div x-show="error" class="mt-4 p-3 bg-red-100 text-red-700 rounded-lg" x-text="error"></div>
  </div>

  <!-- Charts Grid -->
  <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
    <!-- Percentile Chart -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
      <div style="height: 300px">
        <canvas id="percentileChart"></canvas>
      </div>
    </div>

    <!-- Time Series Chart -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
      <div style="height: 300px">
        <canvas id="timeSeriesChart"></canvas>
      </div>
    </div>
  </div>

  <!-- Heatmap -->
  <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4 mb-6">
    <div style="height: 400px">
      <canvas id="heatmapChart"></canvas>
    </div>
  </div>

  <!-- Top N Tables -->
  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
    <!-- Top Slow Endpoints -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow">
      <div class="px-4 py-3 border-b border-gray-200">
        <h3 class="text-lg font-medium text-gray-900 dark:text-white">📉 Slowest Endpoints</h3>
      </div>
      <div class="overflow-x-auto">
        <table id="topSlowTable" class="min-w-full divide-y divide-gray-200">
          <thead class="bg-gray-50 dark:bg-gray-700">
            <tr>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                #
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Endpoint
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Count
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Avg
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Max
              </th>
            </tr>
          </thead>
          <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200">
            <!-- Populated by Alpine.js -->
          </tbody>
        </table>
      </div>
    </div>

    <!-- Top Volume Endpoints -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow">
      <div class="px-4 py-3 border-b border-gray-200">
        <h3 class="text-lg font-medium text-gray-900 dark:text-white">📊 Highest Volume</h3>
      </div>
      <div class="overflow-x-auto">
        <table id="topVolumeTable" class="min-w-full divide-y divide-gray-200">
          <thead class="bg-gray-50 dark:bg-gray-700">
            <tr>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                #
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Endpoint
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Requests
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Avg
              </th>
            </tr>
          </thead>
          <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200">
            <!-- Populated by Alpine.js -->
          </tbody>
        </table>
      </div>
    </div>

    <!-- Top Error Endpoints -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow">
      <div class="px-4 py-3 border-b border-gray-200">
        <h3 class="text-lg font-medium text-gray-900 dark:text-white">❌ Most Errors</h3>
      </div>
      <div class="overflow-x-auto">
        <table id="topErrorsTable" class="min-w-full divide-y divide-gray-200">
          <thead class="bg-gray-50 dark:bg-gray-700">
            <tr>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                #
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Endpoint
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Total
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Errors
              </th>
              <th
                class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
              >
                Rate
              </th>
            </tr>
          </thead>
          <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200">
            <!-- Populated by Alpine.js -->
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>
